﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using XGetoptCS;
using System.IO;
using System.Resources;
using System.Diagnostics;

namespace msgfmt
{
    public enum FileFormat
    {
        PoFile,
        KeyValuePairFile
    }

    class ProgramOpt
    {
        public ProgramOpt()
        {
            FileFormat = msgfmt.FileFormat.PoFile;
        }

        public string PoFileName { get; set; }

        public string ResxFileName { get; set; }

        public string ResourcesFileName { get; set; }

        public FileFormat FileFormat { get; set; }
    }

    class Program
    {
        private static void Usage()
        {
            Console.WriteLine("msgfmt -o <out.resources> -i <input.po> -r");
            Console.WriteLine("\n参数说明：");
            Console.WriteLine("\t-o\t生成的.NET .resources后缀名的资源文件");
            Console.WriteLine("\t-i\t要转换的po文件");
            Console.WriteLine("\t-r\t文件格式是键值对的形式");
            Console.WriteLine("\t-h\t打印本帮助");
        }

        private static Dictionary<string, bool> _stringBeingTranslated = new Dictionary<string, bool>();

        static void Main(string[] args)
        {
            var opt = ParseOption(args);
            if (opt == null)
                return;

            using (var reader = new StreamReader(opt.PoFileName))
            {
                using (var writer = new ResourceWriter(opt.ResourcesFileName))
                {
                    switch (opt.FileFormat)
                    {
                        case FileFormat.PoFile:
                            ConvertPo2Resources(reader, writer);
                            break;

                        case FileFormat.KeyValuePairFile:
                            ConvertKeyValueFile2Resources(reader, writer);
                            break;

                        default:
                            throw new NotSupportedException();
                    }
                }
            }
        }

        private static void ConvertKeyValueFile2Resources(StreamReader reader, ResourceWriter writer)
        {
            string line = null;
            int idx = 0;

            while ((line = reader.ReadLine()) != null)
            {
                idx = 0;
                while (idx < line.Length && line[idx] == ' ')
                    idx++;

                if (idx == line.Length)
                    continue;

                if (line[idx] == '#')
                    continue;

                var substrings = line.Split(new char[] { '=' }, 2);
                if (substrings.Length < 2)
                    continue;

                var key = substrings[0];
                var value = substrings[1];

                if (!_stringBeingTranslated.ContainsKey(key))
                {
                    writer.AddResource(key, value);

                    _stringBeingTranslated.Add(key, true);
                }
                else
                {
                    Trace.TraceWarning(string.Format("在第{0}行, 字符串[{1}]已经出现过至少一次了！", idx, key));
                }
            }
        }

        private const string MSGID = "msgid ";
        private const string MSGSTR = "msgstr ";
        private static void ConvertPo2Resources(StreamReader reader, ResourceWriter writer)
        {
            string line = null;
            int idx = 1;

            while ((line = reader.ReadLine()) != null)
            {
                if (line.StartsWith(MSGID))
                {
                    // 跳过引号
                    var key = line.Substring(MSGID.Length + 1, line.Length - MSGID.Length - 2);
                    line = reader.ReadLine();

                    if (!_stringBeingTranslated.ContainsKey(key))
                    {
                        var value = line.Substring(MSGSTR.Length + 1, line.Length - MSGSTR.Length - 2);
                        writer.AddResource(key, value);

                        _stringBeingTranslated.Add(key, true);
                    }
                    else
                    {
                        Trace.TraceWarning(string.Format("在第{0}行, 字符串[{1}]已经出现过至少一次了！", idx, key));
                    }
                }
            }
        }

        private static ProgramOpt ParseOption(string[] args)
        {
            var parser = new XGetopt();
            char c = '\0';
            var opt = new ProgramOpt();
            while ((c = parser.Getopt(args.Length, args, "ho:i:r")) != '\0')
            {
                switch (c)
                {
                    case 'o':
                        opt.ResourcesFileName = Path.GetFullPath(parser.Optarg);
                        break;

                    case 'i':
                        opt.PoFileName = Path.GetFullPath(parser.Optarg);
                        break;

                    case 'r':
                        opt.FileFormat = FileFormat.KeyValuePairFile;
                        break;

                    case 'h':
                    default:
                        Usage();
                        return null;
                }
            }

            return opt;
        }
    }
}
